home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
editor
/
j414src.arc
/
PORTSRV.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-10
|
4KB
|
152 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
/* This is a server for jove sub processes. By the time we get here, our
standard output goes to jove's process input. */
#include "jove.h"
#if defined(IPROCS) && defined(PIPEPROCS) /* the whole file! */
#include <signal.h>
#include <sys/ioctl.h>
#include "wait.h"
private struct header {
int pid;
int nbytes;
char buf[512];
} header;
private int tty_fd;
#define HEADSIZE ((sizeof header.pid) + sizeof (header.nbytes))
private void
proc_write(ptr, n)
UnivConstPtr ptr;
size_t n;
{
(void) write(1, ptr, n);
}
private void
read_pipe(fd)
int fd;
{
register size_t n;
while ((header.nbytes = read(fd, header.buf, sizeof header.buf)) > 0) {
n = HEADSIZE + header.nbytes;
proc_write((UnivConstPtr) &header, n);
}
}
private void
proc_error(str)
char *str;
{
header.pid = getpid();
header.nbytes = strlen(str);
strcpy(header.buf, str);
proc_write((UnivConstPtr) &header, header.nbytes + HEADSIZE);
write(tty_fd, str, strlen(str));
exit(-2);
}
/* ARGSUSED */
int
main(argc, argv)
int argc;
char *argv[];
{
int p[2];
int pid;
if (pipe(p) == -1)
proc_error("Cannot pipe jove portsrv.\n");
switch (pid = fork()) {
case -1:
proc_error("portsrv: cannot fork.\n");
/*NOTREACHED*/
case 0:
/* We'll intercept childs output in p[0] */
(void) dup2(p[1], 1);
(void) dup2(p[1], 2);
(void) close(p[0]);
(void) close(p[1]);
(void) setpgrp(getpid(), getpid());
execv(argv[1], (const char **) &argv[2]);
_exit(-4);
/*NOTREACHED*/
default:
(void) close(0);
tty_fd = open("/dev/tty", 1);
#ifdef NEVER
{
int i;
for (i = 0; i < argc; i++) {
write(tty_fd, "*argv++ = ", 10);
write(tty_fd, argv[i], strlen(argv[i]));
write(tty_fd, "\n", 1);
}
}
#endif /* NEVER */
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
(void) close(p[1]);
/* tell jove the pid of the real child as opposed to us */
header.pid = getpid();
header.nbytes = sizeof (int);
*(int *) header.buf = pid;
(void) write(1, (char *) &header, sizeof pid + HEADSIZE);
/* read proc's output and send it to jove */
read_pipe(p[0]);
/* received EOF - wait for child to die and then exit
ourself in the same way so that JOVE knows how the
child died. This is sort of a kludge, but the alternative
is to write the childs status to JOVE, which seems sorta
yucky, too.
Actually, 4 or 5 years later I like that idea much better,
so remind me to implement it that way when I get a chance.
7-23-89 Gee thanks, whoever implemented this for me! */
(void) close(p[0]);
header.pid = getpid();
header.nbytes = EOF; /* tell jove we are finished */
/* try to exit like our child did ... */
{
union wait status;
while (wait(&status) != pid)
;
*(int *) header.buf = status.w_status;
}
(void) write(1, (UnivConstPtr) &header, HEADSIZE + sizeof (int));
}
return 0;
}
#else /* IPROCS && PIPEPROCS */
int
main()
{
return 0;
}
#endif